package csel.view.status;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.List;

import csel.model.*;
import csel.model.entity.Character;
import csel.model.skills.*;

import javax.imageio.ImageIO;
import javax.swing.*;

public class SkillBar extends JPanel implements Observer<Object>, IndexedBar
{

	private static final long serialVersionUID = 1L;

	private Character myCharacter;
	
	private int startIndex;
	private int modeIndex;
	private char currentMode; //a is all, c is active, n is nonranged
	
	private JLabel[] skillLabels;
	
	private JLabel currentIcon;
	private JLabel rotateIcon;
	private JLabel invIcon;
	private JLabel equipmentIcon;
	
	private ImageIcon useSelfIcon;
	private ImageIcon useOtherIcon;
	private ImageIcon upgradeIcon;
	private ImageIcon emptyIcon;
	
	
	public static SkillBar initialize(Character myCharacter)
	{
		SkillBar theSkillBar = new SkillBar(myCharacter);
		myCharacter.addObserver(theSkillBar);
		return theSkillBar;
	}
	
	private SkillBar(Character myCharacter)
	{
		this.myCharacter = myCharacter;
		
		setLayout(new BoxLayout(this,BoxLayout.LINE_AXIS));
		
		skillLabels = new JLabel[10];
		for (int a = 0; a < 10; ++a)
		{
			JLabel tempLabel = new JLabel(Integer.toString((a+1) % 10));
			tempLabel.setVerticalAlignment(JLabel.NORTH);
			tempLabel.setForeground(Color.white);

			add(tempLabel);
			add(skillLabels[a] = new JLabel());
		}
		
		rotateIcon = ImageLoader.makeLabel("rotate_icon");
		equipmentIcon = ImageLoader.makeLabel("equip_mode_icon");
		invIcon = ImageLoader.makeLabel("inv_mode_icon");
		
		useSelfIcon = ImageLoader.makeIcon("useself_skill_icon");
		useOtherIcon = ImageLoader.makeIcon("useother_skill_icon");
		upgradeIcon = ImageLoader.makeIcon("upgrade_skill_icon");
		emptyIcon = ImageLoader.makeIcon("emptyslot");
		
		currentIcon = new JLabel(useSelfIcon);
		
		JLabel tempLabel1 = new JLabel(" - ");
		tempLabel1.setVerticalAlignment(JLabel.NORTH);
		tempLabel1.setForeground(Color.white);
		add(tempLabel1);
		add(currentIcon);
		
		JLabel tempLabel2 = new JLabel(" = ");
		tempLabel2.setVerticalAlignment(JLabel.NORTH);
		tempLabel2.setForeground(Color.white);
		add(tempLabel2);
		add(rotateIcon);

		
		JLabel tempLabel3 = new JLabel(" I ");
		tempLabel3.setVerticalAlignment(JLabel.NORTH);
		tempLabel3.setForeground(Color.white);
		add(tempLabel3);
		add(invIcon);
		
		JLabel tempLabel4 = new JLabel(" E ");
		tempLabel4.setVerticalAlignment(JLabel.NORTH);
		tempLabel4.setForeground(Color.white);
		add(tempLabel4);
		add(equipmentIcon);
		
		setMode(modeIndex);
		setLabels();
		
		setOpaque(false);
	}
	
	public void rotate()
	{
		SkillsProxy myProxy = myCharacter.getMySkills();
		int totalSkills;
		if (currentMode == 'a')
		{
			totalSkills = myProxy.getAllSkills().size();
		}
		else if (currentMode == 'c')
		{
			totalSkills = myProxy.getActiveSkills().size();
		}
		else
		{
			totalSkills = myProxy.getNonRangedSkills().size();
		}
		if (totalSkills <= 10)
			return;
		startIndex += 10;
		if (startIndex > totalSkills)
			startIndex = 0;
		
		setLabels();
	}
	
	public void mupdate(Object o, Object param)
	{
		if (o.equals(myCharacter))
		{
			//TODO: make this not reset the index if not necessary
			startIndex = 0;
			setLabels();
		}
	}
	
	public int getOffset()
	{
		return startIndex;
	}
	
	public void setCharacter(Character c)
	{
		myCharacter = c;
		myCharacter.addObserver(this);
		setLabels();
	}
	
	public void setMode(int i)
	{
		startIndex = 0;
		modeIndex = i;
		
		if (i == 0)
		{
			currentIcon.setIcon(useSelfIcon);
			currentMode = 's';
		}
		else if (i == 1)
		{
			currentIcon.setIcon(useOtherIcon);
			currentMode = 'c';
		}
		else
		{
			currentIcon.setIcon(upgradeIcon);
			currentMode = 'a';
		}
		
		setLabels();
	}
	
	public void nextMode()
	{
		modeIndex = ++modeIndex % 3;
		setMode(modeIndex);
	}
	
	private void setImage(JLabel myLabel, String filename)
	{
		try
		{
			myLabel.setIcon(new ImageIcon(ImageIO.read(new File("images/"+filename+".png")).getSubimage(0, 0, 30, 45)));
		}
		catch (IOException exc)
		{
			System.out.println("SkillBar.setImage() - image: "+filename+" not found!  Using text instead");
			myLabel.setText(filename);
		}
	}
	
	private void setLabels()
	{
		SkillsProxy myProxy = myCharacter.getMySkills();
		
		int totalSkills = 0;
		int upperBound = startIndex+10;
		int index = 0;
		
		if (currentMode == 'a')
		{
			
			List<Skill> mySkills = myProxy.getAllSkills();
			totalSkills = mySkills.size();

			for (int a = startIndex; (a < totalSkills)&&(a < upperBound); ++a)
			{
				setImage(skillLabels[index++],mySkills.get(a).getName());
			}
			while (index < 10)
			{
				skillLabels[index++].setIcon(emptyIcon);
			}
		}
		else if (currentMode == 'c')
		{
			List<ActiveSkill> mySkills = myProxy.getActiveSkills();
			totalSkills = mySkills.size();

			for (int a = startIndex; (a < totalSkills)&&(a < upperBound); ++a)
			{
				setImage(skillLabels[index++],mySkills.get(a).getName());
			}
			while (index < 10)
			{
				skillLabels[index++].setIcon(emptyIcon);
			}
		}
		else
		{
			List<NonRangedActiveSkill> mySkills = myProxy.getNonRangedSkills();
			totalSkills = mySkills.size();

			for (int a = startIndex; (a < totalSkills)&&(a < upperBound); ++a)
			{
				setImage(skillLabels[index++],mySkills.get(a).getName());
			}
			while (index < 10)
			{
				skillLabels[index++].setIcon(emptyIcon);
			}
		}
		
		revalidate();
		repaint();
	}
	
	private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException
    {
            throw new java.io.NotSerializableException("SkillBar should not be serialized.");
    }
    
    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException
    {
            throw new java.io.NotSerializableException("SkillBar should not be serialized.");
    }

}
